﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using EnvDTE;
using Microsoft.VisualStudio.Shell.Interop;
using EnvDTE80;

namespace CUSTIS.BatchReplace
{
    /// <summary>
    /// Interaction logic for MyControl.xaml
    /// </summary>
    public partial class BatchReplaceControl : UserControl
    {
        private readonly IServiceProvider _serviceProvider;


        public BatchReplaceControl(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
            InitializeComponent();
        }

        private void BtnOk_Click(object sender, RoutedEventArgs e)
        {
            TbxFindWhat.Text = TbxFindWhat.Text.Replace("(?<!\r)\n", Environment.NewLine);
            TbxReplaceWith.Text = TbxReplaceWith.Text.Replace("(?<!\r)\n", Environment.NewLine);

            var findWhat = TbxFindWhat.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
            var replaceWith = TbxReplaceWith.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);

            Debug.Assert(findWhat.Length == replaceWith.Length);
            var dte = (DTE2)_serviceProvider.GetService(typeof(SDTE));
            var find = (Find2)dte.Find;
            if (find == null)
            {
                return;
            }

            for (var i = 0; i < findWhat.Length; i++)
            {
                Replace(findWhat[i], replaceWith[i], find);
            }
        }

        private void Replace(string findWhat, string replaceWith, Find2 find)
        {
            // Make sure all docs are searched before displaying results.
            find.WaitForFindToComplete = true;

            vsFindTarget target = getSelectedTarget();


            var options = vsFindOptions.vsFindOptionsFromStart;
            if (CbxMatchCase.IsChecked.Value)
            {
                options |= vsFindOptions.vsFindOptionsMatchCase;
            }
            if (CbxWholeWord.IsChecked.Value)
            {
                options |= vsFindOptions.vsFindOptionsMatchWholeWord;
            }
            if (CbxRegex.IsChecked.Value)
            {
                options |= vsFindOptions.vsFindOptionsRegularExpression;
            }

            var searchPath = "";
            if (target == vsFindTarget.vsFindTargetFiles)
            {
                searchPath = TbxBrowse.Text;
                options |= vsFindOptions.vsFindOptionsSearchSubfolders;
            }

            try
            {

                var result = find.FindReplace(vsFindAction.vsFindActionReplaceAll, findWhat,
                                 (int)options, replaceWith,
                                 target, searchPath,
                                 TbxFileTypes.Text, vsFindResultsLocation.vsFindResults2);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Unable to replace files. Error: " + ex.Message);
            }
        }

        private void CbxTarget_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (stackBrowse != null)
            {
                if (getSelectedTarget() == vsFindTarget.vsFindTargetFiles)
                {
                    stackBrowse.Visibility = Visibility.Visible;
                    lblBrowse.Visibility = Visibility.Visible;
                }
                else
                {
                    stackBrowse.Visibility = Visibility.Collapsed;
                    lblBrowse.Visibility = Visibility.Collapsed;
                    TbxBrowse.Text = "";
                }
            }
        }

        private vsFindTarget getSelectedTarget()
        {
            var item = (ComboBoxItem)CbxTarget.SelectedItem;
            vsFindTarget target;
            Enum.TryParse(item.Name, out target);
            return target;
        }

        private void btnBrowse_Click(object sender, RoutedEventArgs e)
        {
            var dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.Multiselect = true;
            dlg.ValidateNames = false;
            dlg.CheckFileExists = false;
            dlg.CheckPathExists = true;
            dlg.FileName = "Folder Selection";

            var result = dlg.ShowDialog();

            if (result == true)
            {
                TbxBrowse.Text = "";

                foreach (var file in dlg.FileNames)
                {
                    TbxBrowse.Text += file.Replace("Folder Selection", String.Empty) + ";";
                }
            }
        }
    }
}